﻿using System;
using System.Collections.Generic;


namespace MainEntities
{
    public enum Priority { High /* Высокий*/, Medium /* Средний*/, Low /* Низкий*/};

    public enum Relations {FinishToStart, StartToStart, FinishToFinish, StartToFinish};

    public enum Status { notAssigned /* Не Принята*/, draft /* Черновик*/, put /* Поставлена*/, 
        adopted /* Принята*/, solving /* Решается*/, solved /* Решена*/, verifying /* Проверяется*/, 
        expect /* Ожидает*/, completed /* Завершена*/, rejected /* Отклонена*/ };

    public delegate void StatusChangedEventHandler(object sender,
StatusChangedEventArgs e);

    

    public class StatusChangedEventArgs : EventArgs
    {
        public Status status;

        public StatusChangedEventArgs(Status _status)
        {
            status = _status;
        }
    }


    public class Task
    {
        private int _taskID;
        public int TaskID
        {
            get
            {
                return _taskID;
            }

            set
            {
                if (value != _taskID)
                    _taskID = value;
            }
        }
      
        private string name;

        public string Name 
        {
            get { return name; }
            set { name = value; }
        }

        private bool _canSolve;

        public bool CanSolve
        {
            get { return _canSolve; }
            set { _canSolve = value; }
        }
        string description;
        DateTime plannedStartExecution;
        DateTime plannedFinishExecution;
        DateTime actualStartExecution;
        DateTime actualFinishExecution;
        Priority taskPriority;
        Status taskStatus;
        private User implementer;
        private TaskReferences _interactionType;
        Task parent;
        List<Task> children;
        
        public Task(int _taskID, string _name, string _description, DateTime _plannedStartExecution, DateTime _plannedFinishExecution, Priority _taskPriority,
            TaskReferences taskRef = null)
        {
            //TaskID = getAvailibleTaskID();
            TaskID = _taskID;
            if (String.IsNullOrEmpty(_name))
                name = _name;
            if (String.IsNullOrEmpty(_description))
                description = _description;
            plannedStartExecution = _plannedStartExecution;
            plannedFinishExecution = _plannedFinishExecution;
            taskPriority = _taskPriority;
            if (taskRef != null)
                _interactionType = new TaskReferences(taskRef);

            //MainPage.statusChanged += new StatusChangedEventHandler(task_statusChanged);
        }

        // Конструктор без TaskID
        public Task() 
        {
            
            //TaskID = getAvailibleTaskID();
            taskStatus = Status.notAssigned;
            //MainPage.statusChanged += new StatusChangedEventHandler(task_statusChanged);
        }

        public TaskReferences InteractionType
        {
            get
            {
                return _interactionType;
            }

            set
            {
                if (value != _interactionType)
                    _interactionType = value;
            }
        }

        public User Implementer
        {
            get
            {
                return implementer;
            }

            set
            {
                if (value != implementer)
                    implementer = value;
            }
        }



        private void task_statusChanged(object sender, StatusChangedEventArgs e)
        {
            taskStatus = e.status;
        }


        //static int getAvailibleTaskID()
        //{
        //    return ++lastTaskID;
        //}        
    }


    public class Project
    {
        #region Поля
        //static int lastProjectID = 0;
        public string Name {get; set;}
        private int _projectID;
        

        public int ProjectID
        {
            get { return _projectID; }
            set { _projectID = value; }
        }

        string description;
        List<string> basicDocumentation;
        DateTime plannedStartExecution;
        DateTime plannedFinishExecution;
        DateTime actualStartExecution;
        DateTime actualFinishExecution;
        Status projectStatus;
        //User implementer;
        Priority projectPriority;
        TimeSpan recoverTime;
        Dictionary<int,Task> taskContainer; // в проекте хранить список всех задач, которые в него входят?
        //Dictionary<Task, TaskReferences> taskContainer;
        #endregion

        //static int getAvailibleProjectID()
        //{
        //    return ++lastProjectID;
        //}    

        public Task getTaskById(int id)
        {
            return taskContainer[id];
        }

        public void addTaskToProject(Task taskToAdd, TaskReferences referencesSet)
        {
            taskToAdd.InteractionType = referencesSet;
            taskContainer.Add(taskToAdd.TaskID, taskToAdd);
        }

        public void addTaskToProject(Task taskToAdd)
        {
            addTaskToProject(taskToAdd, new TaskReferences());
        }

        public void addRelationBetweenTasks(int taskID1, List<int> taskID2, Relations rel)
        {

            
            // связь идет из первой задачи во вторую
            switch (rel)
            {
                case Relations.FinishToFinish:
                    taskContainer[taskID1].InteractionType.FinishToFinish.AddRange(taskID2);
                    break;

                case Relations.FinishToStart:
                    taskContainer[taskID1].InteractionType.FinishToStart.AddRange(taskID2);
                    break;

                case Relations.StartToFinish:
                    taskContainer[taskID1].InteractionType.StartToFinish.AddRange(taskID2);
                    break;

                case Relations.StartToStart:
                    taskContainer[taskID1].InteractionType.StartToStart.AddRange(taskID2);
                    break;

                default:

                    break;
            }


        }

        #region Конструкторы
        // Конструктор без ProjectID
        public Project()
        {
            //ProjectID = getAvailibleProjectID();
            taskContainer = new Dictionary<int, Task>();
            Name = "Проект №  " + _projectID.ToString();
        }

        public Project(int _projectID, string _name, string _description, List<string> _basicDocumentation,
            DateTime _plannedStartExecution, DateTime _plannedFinishExecution, Priority _projectPriority,
            TimeSpan _recoverTime, Dictionary<int, Task> _taskContainer)
        {

            _projectID = _projectID;
            string nullString = "Нет данных";

            Name = (String.IsNullOrEmpty(_name)) ? nullString : _name;

            description = (String.IsNullOrEmpty(_description)) ? nullString : _description;


            if ((_basicDocumentation != null) && (_basicDocumentation.Count == 0))
                basicDocumentation = new List<string>(_basicDocumentation);
            else
                basicDocumentation = new List<string>();

            plannedFinishExecution = (_plannedFinishExecution == null) ? DateTime.Now : _plannedFinishExecution;

            plannedStartExecution = (_plannedStartExecution == null) ? DateTime.Now : _plannedStartExecution;

            projectPriority =  _projectPriority;

            recoverTime = (_recoverTime == null) ? TimeSpan.Zero : _recoverTime;


            if ((_taskContainer != null) && (_taskContainer.Count == 0))
                taskContainer = new Dictionary<int, Task>(_taskContainer);
            else
                taskContainer = new Dictionary<int, Task>();

        }

        #endregion





    }

    public class TaskReferences
    {
        private List<int> _finishToStart; // задачи, которые связаны с задачей, в которой хранится экземпляр TaskReferences
        private List<int> _startToStart; // типом связи finishToStart.
        private List<int> _finishToFinish;
        private List<int> _startToFinish;

        public List<int> FinishToStart
        {
            get
            {
                return _finishToStart;
            }

            set
            {
                if (value != _finishToStart)
                    _finishToStart = value;
            }
        }

        public List<int> StartToStart
        {
            get
            {
                return _startToStart;
            }

            set
            {
                if (value != _startToStart)
                    _startToStart = value;
            }
        }

        public List<int> FinishToFinish
        {
            get
            {
                return _finishToFinish;
            }

            set
            {
                if (value != _finishToFinish)
                    _finishToFinish = value;
            }
        }

        public List<int> StartToFinish
        {
            get
            {
                return _startToFinish;
            }

            set
            {
                if (value != _startToFinish)
                    _startToFinish = value;
            }
        }


        public TaskReferences()
        {
            _finishToStart = new List<int>(0);
            _startToStart = new List<int>(0);
            _finishToFinish = new List<int>(0);
            _startToFinish = new List<int>(0);
        }

        public TaskReferences(List<int> fTs, List<int> sTs, List<int> fTf, List<int> sTf)
        {
            _finishToStart = new List<int>(fTs);
            _startToStart = new List<int>(sTs);
            _finishToFinish = new List<int>(fTf);
            _startToFinish = new List<int>(sTf);
        }

        public TaskReferences(TaskReferences t)
        {

            _finishToStart = new List<int>(t.FinishToStart);
            _startToStart = new List<int>(t.StartToStart);
            _finishToFinish = new List<int>(t.FinishToStart);
            _startToFinish = new List<int>(t.StartToFinish);
        }
               

    }

}
